package com.zmn.oms.third.suning;

import com.alibaba.fastjson.JSON;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.HttpUtil;
import com.zmn.oms.third.suning.dto.SuningRequestDTO;
import com.zmn.oms.third.suning.dto.SuningResponseBaseDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.net.URLEncoder;
import java.util.Base64;
import java.util.List;
import java.util.Objects;

/**
 * 苏宁保外渠道对接的工具类
 *
 * @author xiewenbing
 * @date 2021/01/05 18:00
 */
@Slf4j
public class SuningUtil {

    /**
     * 验证苏宁保外渠道发送的数据的签名
     *
     * @param requestDTO
     * @return
     */
    public static boolean verifySign(SuningRequestDTO requestDTO) {

        if (Objects.isNull(requestDTO)) {
            return false;
        }

        StringBuilder sbSignContent = new StringBuilder();
        sbSignContent.append(requestDTO.getApp_key()).append(requestDTO.getMethod()).append(requestDTO.getBody()).
                append(SuningConsts.APP_SECRET);

        String signContent = sbSignContent.toString();
        String sign = Base64.getEncoder().encodeToString(DigestUtils.md5(signContent));

        log.info("【{}】验证签名，【{}】【{}】【{}】",SuningConsts.CHANNEL_NAME,signContent,sign,requestDTO.getSign());

        return Objects.equals(sign,requestDTO.getSign()) ? true : false;
    }

    /**
     * 为同步渠道订单状态数据生成签名
     *
     * @param method
     * @param body
     */
    public static String makeSign(String method, String body) {

        StringBuilder sbSignContent = new StringBuilder();
        sbSignContent.append(SuningConsts.APP_KEY).append(method).append(body).
                append(SuningConsts.APP_SECRET);

        String signContent = sbSignContent.toString();
        String sign = URLEncoder.encode(Base64.getEncoder().encodeToString(DigestUtils.md5(signContent)));

        log.info("【{}】生成签名，【{}】【{}】",SuningConsts.CHANNEL_NAME,signContent,sign);

        return sign;
    }

    /**
     * 解析八段地址
     * @param address
     * @return
     */
    public static String parseAddress(String address) {

        if (StringUtil.isBlank(address)) {
            return "";
        }

        List<String> listAddr = StringUtil.split(address,";",String.class);
        if (CollectionUtil.isNullOrEmpty(listAddr)) {
            return "";
        }

        StringBuilder sbAddr = new StringBuilder();
        for (int i=1;i<listAddr.size();i++) {
            sbAddr.append(listAddr.get(i));
        }

        return sbAddr.toString();
    }

    /**
     * 失败应答
     *
     * @param message
     * @return
     */
    public static String failedResponse(String message) {

        SuningResponseBaseDTO responseBaseDTO = new SuningResponseBaseDTO();
        responseBaseDTO.setReturnCode(SuningConsts.RESPONSE_CODE_FAILED);
        responseBaseDTO.setReturnMessage(message);

        return JSON.toJSONString(responseBaseDTO);
    }

    /**
     * 发送http请求
     * @param method
     * @param body
     * @return
     * @throws OmsBaseException
     */
    public static String postHttpRequest(String method, String body) {

        if (StringUtil.isBlank(method) || StringUtil.isBlank(body)) {
            log.info("【{}】发送请求失败，参数不能为空",SuningConsts.CHANNEL_NAME);
            return null;
        }

        // 生成签名
        String sign = makeSign(method, body);

        // url
        String url = String.format(SuningConsts.API_URL, method, SuningConsts.APP_KEY, sign);

        log.info("【{}】发送请求，URL【{}】,数据【{}】",SuningConsts.CHANNEL_NAME,url,body);

        String response = "";
        for (int i=0; i<3; i++) {
            try {
                if (url.matches("https(.*)")) {
                    response = HttpUtil.httpsPost(url, body);
                } else {
                    response = HttpUtil.httpPost(url, body);
                }

                if (StringUtil.isNotBlank(response)) {
                    break;
                }
            } catch (Exception exception) {
                log.info("【{}】发送请求失败,{}",SuningConsts.CHANNEL_NAME,Objects.nonNull(exception)? exception.getMessage():"网络请求异常");
            }
        }

        log.info("【{}】发送请求应答【{}】",SuningConsts.CHANNEL_NAME,response);
        return response;
    }
}
